import Vue from 'vue'
import Vuex from 'vuex'
import pako from 'pako'
Vue.use(Vuex)


export default new Vuex.Store({
  state: {
    wsurl: '', //ws地址
    ws: null, //建立的连接
    lockReconnect: false, //是否真正建立连接
    timeout: 30000, //x秒一次心跳
    timeoutObj: null, //心跳心跳倒计时
    serverTimeoutObj: null, //心跳倒计时
    timeoutnum: null, //断开 重连倒计时
    isState: false,   //连接状态
    msg: null //接收到的信息
  },
  getters: {
    // 获取接收的信息
    socketMsgs: state => {
      return state.msg
    },
    // 获取链接状态
    getState: state => {
      return state.isState
    }
  },
  mutations: {
    //初始化ws
    webSocketInit(state, url) {
      let that = this
      state.wsurl = url;
      //this 创建一个state.ws对象【发送、接收、关闭socket都由这个对象操作】
      state.ws = new WebSocket(state.wsurl);

      state.ws.onopen = function (res) {
        clearTimeout(connectTimer); // WebSocket已连接成功，清除计时器
        console.log("Connection success...");
        state.isState = true
        /**
         * 启动心跳检测
         */
        that.commit("start");
      }

      var connectTimer = setTimeout(() => {
        if (!state.isState) {
          console.log('WebSocket connection timed out');
          state.ws.close(); // 手动关闭WebSocket
        }
      }, 3000); // 设置超时时间为5秒

      state.ws.onmessage = function (res) {
        // 解压数据
        let base64String = res.data;
        let padding = '='.repeat((4 - base64String.length % 4) % 4);
        let base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
        let rawData = window.atob(base64);
        let outputArray = new Uint8Array(rawData.length);
        for (var i = 0; i < rawData.length; ++i) {
          outputArray[i] = rawData.charCodeAt(i);
        }
        let info = pako.inflateRaw(outputArray, { to: 'string' })

        var data = JSON.parse(info);
        if (data.type === 'ping') {
          // 收到服务器信息，心跳重置
          that.commit("reset");
        } else {
          state.msg = data;
        }
      }
      state.ws.onclose = function (res) {
        console.log("Connection closed...");
        state.isState = false
        //重连
        that.commit('reconnect');
      }
      state.ws.onerror = function (res) {
        console.log("Connection error...");
        state.isState = false
        //重连
        that.commit('reconnect');
      }
    },
    reconnect(state) {
      //重新连接
      let that = this;
      if (state.lockReconnect) {
        return;
      }
      state.lockReconnect = true;
      //没连接上会一直重连,30秒重试请求重连，设置延迟避免请求过多
      state.timeoutnum && clearTimeout(state.timeoutnum);
      state.timeoutnum = setTimeout(() => {
        //新连接
        that.commit('webSocketInit', state.wsurl)
        state.lockReconnect = false;
      }, 500);
    },
    reset(state) {
      //重置心跳
      let that = this;
      //清除时间
      clearTimeout(state.timeoutObj);
      clearTimeout(state.serverTimeoutObj);
      //重启心跳
      that.commit('start')
    },
    start(state) {
      //开启心跳
      var self = this;
      state.timeoutObj && clearTimeout(state.timeoutObj);
      state.serverTimeoutObj && clearTimeout(state.serverTimeoutObj);
      state.timeoutObj = setTimeout(() => {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (state.ws.readyState === 1) {
          //如果连接正常
          self.commit("webSocketSend", { type: 'ping' });
        } else {
          //否则重连
          self.commit('reconnect');
        }
        state.serverTimeoutObj = setTimeout(function () {
          //超时关闭
          state.ws.close();
        }, state.timeout);
      }, state.timeout);
    },
    webSocketSend(state, data) {
      if (state.ws.readyState === 1) {
        state.ws.send(JSON.stringify(data));
      } else {
        console.log(state.ws.readyState)
      }
    }
  },
  actions: {
    webSocketInit({
      commit
    }, url) {
      commit('webSocketInit', url)
    },
    webSocketSend({
      commit
    }, data) {
      commit('webSocketSend', data)
    }
  }
})